#include"VertexHelper.hlsli"
#include"Light.hlsli"

cbuffer CBPerFrame : register(b1)
{
    float4x4 g_View;
    float4x4 g_Proj;
    float3 gCamPos;
    float pad;
}
#define MaxPoinLight 10
cbuffer PSConstantBuffer : register(b2)
{
    DirectionalLight g_DirLight;
    PointLight g_PointLight[MaxPoinLight];
    SpotLight g_SpotLight;
    int pointCount;
    float g_Pad[3];
}

#include "DeferredOutTex.hlsli"
// ----------------------------------------------------------------------------

float Fwin(float d, float radius)
{
    float ratio = d / radius;
    float ratio2 = ratio * ratio;
    float ratio4 = ratio2 * ratio2;
    float falloff = max(0, 1 - ratio4);
    return falloff * falloff;
}

float4 PS(VertexOut pIn) : SV_Target
{
    clip(gWorldPosTexture.Sample(g_Sam, pIn.uv).a - 0.0001f);
    float4 packedAlbedo = gAlbedoTexture.Sample(g_Sam, pIn.uv);
    int lightNo = gNormalTexture.Sample(g_Sam, pIn.uv).a;
    int isLight = packedAlbedo.a;
    [flatten]
    if (isLight >= 1)
    {
        float3 I = g_PointLight[lightNo].Color * g_PointLight[lightNo].Intensity;
        return float4(I, 1.0f);
    }
    float3 albedo = packedAlbedo.rgb;
    float3 normal = gNormalTexture.Sample(g_Sam, pIn.uv).rgb;
    float3 worldPos = gWorldPosTexture.Sample(g_Sam, pIn.uv).rgb;
    float roughness = gOrmTexture.Sample(g_Sam, pIn.uv).g;
    float metal = gOrmTexture.Sample(g_Sam, pIn.uv).b;
    
    float3 kd = albedo;
    float3 brdf = kd / PI;
    float3 ks = gOrmTexture.Sample(g_Sam, pIn.uv).rgb;
    float alpha = gOrmTexture.Sample(g_Sam, pIn.uv).a;
    // 标准化法向量
    normal = normalize(normal);

    float3 ambient, diffuse, spec;

    ambient = diffuse = spec = 0;
    [unroll]
    for (int i = 0; i < pointCount; i ++)
    {
        float3 I = g_PointLight[i].Color * g_PointLight[i].Intensity;
        // 顶点指向眼睛的向量
        float3 toEyeW = normalize(gCamPos - worldPos);
        float3 toLight = normalize(g_PointLight[i].Position - worldPos);
    
        float dist = length(worldPos - g_PointLight[i].Position);
        float falloff = Fwin(dist, g_PointLight[i].Range);
        //ambient += float3(0.1f, 0.1f, 0.1f) * I;
        diffuse += I * brdf * max(0, dot(normal, toLight)) * PI * 2 * (1.0f / (dist * dist)) * falloff; //kd * (I / (dist * dist)) * max(0, dot(normal, toLight));
        //spec += ks * (I / (dist * dist)) * pow(max(0, dot(normal, normalize(toEyeW + toLight))), alpha);
 
    }
    
       // Reinhard色调映射
    float3 mapped = diffuse / (diffuse + float3(1.0f,1.0f,1.0f));
    
    return float4(sqrt(mapped), 1.0f);
    return float4(ambient + diffuse + spec, 0);
}
